from fastapi import Request
from pydantic import BaseModel
from tortoise.transactions import atomic, in_transaction

from service import RepositoryService, UserService, CollaboratorService, BookService
from common.result.Result import Result
from common.enum import BaseEnum
from common.const import BaseConstant
from util.redis import Redis
from util.str import Str
from util.log import Log
from util.token import Token
from util.time import Time

class Body(BaseModel):
    parentId: str = None
    type: str
    repositoryShortUri: str

async def CreateBook(req: Request, body: dict):
    try:
        async with in_transaction() as connection:
            type = body.get('type')
            repositoryShortUri = body.get("repositoryShortUri")
            if Str.isBlank(type, repositoryShortUri):
                Log.error('参数为空，检查参数')
                return Result.error(BaseEnum.PARAMETER_INVALID_ERROR)
            
            token = req.headers.get("token")
            user = await UserService.getUserByToken(token)
            if user == None:
                Log.error('用户不存在')
                return Result.error(BaseEnum.USER_NOT_EXISTS_ERROR)
            
            repository = await RepositoryService.getRepositoryByShortUri(repositoryShortUri)
            if repository == None:
                Log.error('repository 不存在')
                return Result.error(BaseEnum.REPOSITORY_NOT_EXISTS_ERROR)

            if user.id != repository.user_id:
                isCollaborator = await CollaboratorService.isCollaborator(repository.id, user.id)
                if isCollaborator == False:
                    Log.error('非协作者，无法创建')
                    return Result.error(BaseEnum.USER_NOT_REPOSITORY_COLLABORATOR_ERROR)

            book = {
                "parent_id": 0 if body.get("parentId") == None else body.get("parentId"),
                "repository_id": repository.id,
                "user_id": user.id,
                "type": type,
                "content": "> 你好",
                "short_uri": await uniqueShortUri(16),
            }

            res = await BookService.createBook(book)
            if res == None:
                Log.error('创建 book 失败')
                return Result.error(BaseEnum.CREATE_BOOK_ERROR)
            
            # 删除 book tree 的缓存
            key = BaseConstant.BOOK_TREE_KEY % repositoryShortUri
            Redis.deleteItem(key)

            return Result.success(res)
    except Exception as e:
        Log.error('创建 book 异常', e)
        return Result.error(BaseEnum.SERVICE_ERROR)

async def uniqueShortUri(len):
    objList = await BookService.allShortUriList()
    shortUriList = [item.get('short_uri') for item in objList]

    shortUri = Str.generateRandomString(len)
    while shortUri in shortUriList:
        shortUri = Str.generateRandomString(len)
        
    return shortUri